package com.obc.quantity;

//Understands measurement manipulations
public class Quantity {

	private final double value; 
	private final Unit unit; 
	public Quantity(double value, Unit unit) {
		this.value = value;
		this.unit = unit;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((unit == null) ? 0 : unit.hashCode());
		result = PRIME * result + (int)value;
		return result;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Quantity other = (Quantity) obj;
		if (unit == null) {
			if (other.unit != null)
				return false;
		} 
		if (unit.equals(other.unit)){
			return value == other.value;
		}else{
			return valueInBaseUnit(this) == valueInBaseUnit(other);
		}
	}

	private double valueInBaseUnit(Quantity quantity) {
		return unit.convertToBaseUnit(quantity.value, quantity.unit);
	}
	
	public Quantity add(Quantity other) throws IncompatibleUnitsException {
		if (!this.unit.comparableWith(other.unit)){
			throw new IncompatibleUnitsException();
		}
		if (this.unit.equals(other.unit)){
			return new Quantity(this.value + other.value, this.unit);
		}
		return new Quantity(valueInBaseUnit(this) + valueInBaseUnit(other), Unit.baseUnitFor(this.unit));
		
	}
	
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(this.value);
		sb.append(" ");
		sb.append(unit.name());
		return sb.toString() ;
	}

}










